﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows.Data;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using System.Collections.ObjectModel;
using SilverlightDebateViewModel.SilverlightDebateWS;


namespace SilverlightDebateViewModel
{
    public class StatementsViewModel : INotifyPropertyChanged
    {
        #region Public Properties

        #region VMMainPageViewModel
        private MainPageViewModel _VMMainPageViewModel;
        public MainPageViewModel VMMainPageViewModel
        {
            get { return _VMMainPageViewModel; }
            set
            {
                if (VMMainPageViewModel == value)
                {
                    return;
                }
                _VMMainPageViewModel = value;
                this.NotifyPropertyChanged("VMMainPageViewModel");
            }
        }
        #endregion

        #region Searching
        // True when a search is being perfomrmed
        // So the busy graphic can show
        private bool _Searching = false;
        public bool Searching
        {
            get { return _Searching; }
            private set
            {
                if (Searching == value)
                {
                    return;
                }
                _Searching = value;
                this.NotifyPropertyChanged("Searching");
            }
        }
        #endregion

        #region SearchString
        private string _SearchString;
        public string SearchString
        {
            get { return _SearchString; }
            set
            {
                if (SearchString != value)
                {
                    _SearchString = value;
                    NotifyPropertyChanged("SearchString");
                }
            }
        }
        #endregion

        #region SelectedCategory
        private Category _SelectedCategory;
        public Category SelectedCategory
        {
            get { return this._SelectedCategory; }
            set
            {
                if (this._SelectedCategory != value)
                {
                    this._SelectedCategory = value;
                    this.NotifyPropertyChanged("SelectedCategory");
                }
            }
        }
        #endregion

        #region CategoryList
        private ObservableCollection<Category> _CategoryList = new ObservableCollection<Category>();
        public ObservableCollection<Category> CategoryList
        {
            get { return this._CategoryList; }
            set
            {
                if (this._CategoryList != value)
                {
                    this._CategoryList = value;
                    this.NotifyPropertyChanged("CategoryList");
                }
            }
        }
        #endregion

        #region StatementList
        private ObservableCollection<Statement> _StatementList = new ObservableCollection<Statement>();
        public ObservableCollection<Statement> StatementList
        {
            get { return this._StatementList; }
            set
            {
                if (this._StatementList != value)
                {
                    this._StatementList = value;
                    this.NotifyPropertyChanged("StatementList");
                }
            }
        }
        #endregion

        #region PhantomStatementList
        private List<int> _PhantomStatementList = new List<int>();
        public List<int> PhantomStatementList
        {
            get { return this._PhantomStatementList; }
            set
            {
                if (this._PhantomStatementList != value)
                {
                    this._PhantomStatementList = value;
                    this.NotifyPropertyChanged("PhantomStatementList");
                }
            }
        }
        #endregion

        #region StatementPagedCollection
        private PagedCollectionView _StatementPagedCollection;
        public PagedCollectionView StatementPagedCollection
        {
            get { return this._StatementPagedCollection; }
            set
            {
                if (this._StatementPagedCollection != value)
                {
                    this._StatementPagedCollection = value;
                    this.NotifyPropertyChanged("StatementPagedCollection");
                }
            }
        }
        #endregion

        #region StatementsPerTitlesPage
        private int _StatementsPerTitlesPage = 9;
        public int StatementsPerTitlesPage
        {
            get { return this._StatementsPerTitlesPage; }
            set
            {
                if (this._StatementsPerTitlesPage != value)
                {
                    this._StatementsPerTitlesPage = value;
                    this.NotifyPropertyChanged("StatementsPerTitlesPage");
                }
            }
        }
        #endregion

        #region MaxStatementsPerTitlesPage
        private int _MaxStatementsPerTitlesPage = 25;
        public int MaxStatementsPerTitlesPage
        {
            get { return this._MaxStatementsPerTitlesPage; }
            set
            {
                if (this._MaxStatementsPerTitlesPage != value)
                {
                    if (value < 0 || value > 100)
                        return;
                    this._MaxStatementsPerTitlesPage = value;
                    this.NotifyPropertyChanged("MaxStatementsPerTitlesPage");
                }
            }
        }
        #endregion

        #region CurrentStatementTitlesPageIndex
        private int _CurrentStatementTitlesPageIndex;
        public int CurrentStatementTitlesPageIndex
        {
            get { return this._CurrentStatementTitlesPageIndex; }
            set
            {
                if (this._CurrentStatementTitlesPageIndex != value)
                {
                    this._CurrentStatementTitlesPageIndex = value;
                    this.NotifyPropertyChanged("CurrentStatementTitlesPageIndex");
                }
            }
        }
        #endregion

        #region StatementsPerContentsPage
        private int _StatementsPerContentsPage = 25;
        public int StatementsPerContentsPage
        {
            get { return this._StatementsPerContentsPage; }
            set
            {
                if (this._StatementsPerContentsPage != value)
                {
                    this._StatementsPerContentsPage = value;
                    this.NotifyPropertyChanged("StatementsPerContentsPage");
                }
            }
        }
        #endregion

        #region StatementsStartDate
        private DateTime? _StatementsStartDate = new DateTime?(DateTime.Parse("8/1/2010"));
        public DateTime? StatementsStartDate
        {
            get { return this._StatementsStartDate; }
            set
            {
                if (this._StatementsStartDate != value)
                {
                    this._StatementsStartDate = value;
                    this.NotifyPropertyChanged("StatementsStartDate");
                }
            }
        }
        #endregion

        #region CategoriesPerTitlesPage
        private int _CategoriesPerTitlesPage = 25;
        public int CategoriesPerTitlesPage
        {
            get { return this._CategoriesPerTitlesPage; }
            set
            {
                if (this._CategoriesPerTitlesPage != value)
                {
                    this._CategoriesPerTitlesPage = value;
                    this.NotifyPropertyChanged("CategoriesPerTitlesPage");
                }
            }
        }
        #endregion

        #region CurrentStatementsPage
        private int _CurrentStatementsPage = 1;
        public int CurrentStatementsPage
        {
            get { return this._CurrentStatementsPage; }
            set
            {
                if (this._CurrentStatementsPage != value)
                {
                    this._CurrentStatementsPage = value;
                    this.NotifyPropertyChanged("CurrentStatementsPage");
                }
            }
        }
        #endregion

        #region CurrentCategoriesPage
        private int _CurrentCategoriesPage = 1;
        public int CurrentCategoriesPage
        {
            get { return this._CurrentCategoriesPage; }
            set
            {
                if (this._CurrentCategoriesPage != value)
                {
                    if (value > 0)
                    {
                        this._CurrentCategoriesPage = value;
                        this.NotifyPropertyChanged("CurrentCategoriesPage");
                    }
                }
            }
        }
        #endregion

        #region Visibility_Statements
        private Visibility _Visibility_Statements = Visibility.Collapsed;
        public Visibility Visibility_Statements
        {
            get { return _Visibility_Statements; }
            set
            {
                if (Visibility_Statements == value)
                {
                    return;
                }
                _Visibility_Statements = value;
                this.NotifyPropertyChanged("Visibility_Statements");
            }
        }
        #endregion

        #region AutoLoadStatements
        private bool _AutoLoadStatements = false;
        public bool AutoLoadStatements
        {
            get { return _AutoLoadStatements; }
            set
            {
                if (AutoLoadStatements == value)
                {
                    return;
                }
                _AutoLoadStatements = value;
                this.NotifyPropertyChanged("AutoLoadStatements");
            }
        }
        #endregion

        #endregion Public Properties


        #region Constructors

        public StatementsViewModel()
        {
            LoadCategoriesCommand = new DelegateCommand(LoadCategories, CanLoadCategories);
            LoadStatementsCommand = new DelegateCommand(LoadStatements, CanLoadStatements);
            SetRecordsByPagerCommand = new DelegateCommand(SetRecordsByPager, CanSetRecordsByPager);
            SetStatementPerPageCommand = new DelegateCommand(SetStatementsPerPage, CanSetStatementsPerPage);
            GetSelectedStatementCommand = new DelegateCommand(GetSelectedStatement, CanGetSelectedStatement);
            StatementPagedCollection = new PagedCollectionView(PhantomStatementList);
        }

        #endregion Constructors

        #region Commands

        #region SetRecordsByPagerCommand
        public ICommand SetRecordsByPagerCommand { get; set; }
        public void SetRecordsByPager(object param)
        {
            CurrentStatementTitlesPageIndex = (int)param;
            GetStatements();
        }

        private bool CanSetRecordsByPager(object param)
        {
            return true;
        }
        #endregion

        #region SetStatementsPerPageCommand
        public ICommand SetStatementPerPageCommand { get; set; }
        public void SetStatementsPerPage(object param)
        {
            StatementsPerTitlesPage = (int)param;
        }

        private bool CanSetStatementsPerPage(object param)
        {
            return true;
        }
        #endregion

        #region LoadStatementsCommand
        public ICommand LoadStatementsCommand { get; set; }
        private bool CanLoadStatements(object param)
        {
            return true;
        }

        private void LoadStatements(object param)
        {
            GetStatements();
        }
        #endregion

        #region GetSelectedStatementCommand
        public ICommand GetSelectedStatementCommand { get; set; }
        public void GetSelectedStatement(object param)
        {
            VMMainPageViewModel.SetSelectedStatementToOpen(param);
        }

        private bool CanGetSelectedStatement(object param)
        {
            return true;
        }
        #endregion

        #region LoadCategoriesCommand
        public ICommand LoadCategoriesCommand { get; set; }
        private bool CanLoadCategories(object param)
        {
            return true;
        }

        public void LoadCategories(object param)
        {
            GetCategories();
        }
        #endregion Public Methods

        #endregion Public Methods

        #region Private Methods

        #region GetCategories
        private void GetCategories()
        {
            string baseAddress = VMMainPageViewModel.BaseAddressProperty;
            RIAAuthenticationHeader riaHeader = VMMainPageViewModel.RIAAuthenticationHeaderProperty;

            CategoryList.Clear();
            Searching = true;
            DebateModel.GetCategories(riaHeader, baseAddress, (sender, EventArgs) =>
            {
                if (EventArgs.Error == null && EventArgs.Result.Count > 0 && EventArgs.Result[EventArgs.Result.Count - 1].Errors.Count < 1)
                {
                    foreach (var category in EventArgs.Result)
                        CategoryList.Add(category);
                    this.CurrentStatementTitlesPageIndex = 0;
                }

                // If we have Categories
                // Set the first one as selected
                // Raise AutoLoadStatements so that anything
                // Subscribed to that property will load Statements
                if (CategoryList.Count > 0)
                {
                    SelectedCategory = CategoryList[0];
                    AutoLoadStatements = true;
                }

                Searching = false;
            });
        }
        #endregion

        #region GetStatements
        private void GetStatements()
        {
            string baseAddress = VMMainPageViewModel.BaseAddressProperty;
            RIAAuthenticationHeader riaHeader = VMMainPageViewModel.RIAAuthenticationHeaderProperty;

            Searching = true;
            DebateModel.GetSearchPageOfStatementsWithEmptyContent
                (SelectedCategory.CategoryID, null, null, SearchString, StatementsPerTitlesPage, CurrentStatementTitlesPageIndex, riaHeader, baseAddress,
                    (sender, EventArgs) =>
                    {
                        if (EventArgs.Error == null)
                        {
                            if (EventArgs.Result.StatementList != null)
                            {
                                StatementList = new ObservableCollection<Statement>();
                                StatementsSearchResult result = EventArgs.Result;
                                foreach (var statement in result.StatementList)
                                {
                                    StatementList.Add(statement);
                                }

                                PhantomStatementList.Clear();
                                int nEntries = result.RecordsPerPage * result.TotalPages;
                                for (int nCount = 1; nCount <= nEntries; nCount++)
                                    PhantomStatementList.Add(nCount);
                                StatementPagedCollection.PageSize = result.RecordsPerPage;
                            }
                        }

                        Searching = false;
                    }
                );
        }
        #endregion

        #endregion Private Methods

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion
    }
}